﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lumo.display.animation2D
{
    /// <summary>
    /// Generic animation class.
    /// </summary>
    /// <typeparam name="T">The type of base object</typeparam>
    public abstract class GenericAnimation2D<T> : IInternalAnimation2D, IAnimation2D
        where T : class
    {
        internal T CurrentObject = null;
        internal float Time;
        internal Smooth Smoothness = 0;
        internal Loop LoopMode = Loop.None;

        /// <summary>
        /// Constructor
        /// </summary>
        public GenericAnimation2D(float Time, Smooth Smoothness = Smooth.None, Loop LoopMode = Loop.None, T CurrentObject = null)
        {
            this.Time = Time;
            this.Smoothness = Smoothness;
            this.LoopMode = LoopMode;
            this.CurrentObject = CurrentObject;
        }

        /// <summary>
        /// Setup the object.
        /// </summary>
        /// <param name="ParentObject">The parent object</param>
        public void Setup(object ParentObject)
        {
            // Already setupped.
            if (this.Setupped)
                return;

            if (CurrentObject == null)
            {
                if (!(ParentObject is T))
                    throw new Exception("Invalid Object");
                CurrentObject = ParentObject as T;
            }

            SetupValues();
            this.Setupped = true;
            
        }

        /// <summary>
        /// Reset the object.
        /// </summary>
        public void Reset()
        {
            this.Setupped = false;
        }

        /// <summary>
        /// Setupped check;
        /// </summary>
        public bool Setupped { get; set; }

        /// <summary>
        /// Update the animation.
        /// </summary>
        /// <param name="Game">The game</param>
        public void Update(LumoComponent Game)
        {
            // Not setupped yet.
            if (!this.Setupped)
                Setup(CurrentObject);
            UpdateValues(Game);
        }

        /// <summary>
        /// Finished check.
        /// </summary>
        public abstract bool Finished { get; }
        
        /// <summary>
        /// Finished check.
        /// </summary>
        internal abstract void SetupValues();

        /// <summary>
        /// Update the animation.
        /// </summary>
        /// <param name="Game">The game</param>
        internal abstract void UpdateValues(LumoComponent Game);
    }
}
